package moltencore;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.SocketException;

import moltencore.network.serverlobby.LobbyDemon;
import moltencore.config.Config;
import moltencore.config.ConfigReader;
import moltencore.config.exception.ConfigReaderException;
import moltencore.config.exception.ConfigValidationException;
import moltencore.exception.StartupException;
import moltencore.player.PlayerList;
import moltencore.player.Player;
import spark.network.ServerSender;
import spark.network.ActiveClientList;

public class MoltenCore {
	private static Logger logger = Logger.getLogger(MoltenCore.class);

	private static final String USAGE =
			"<configFile>\n\n" +
			"-configFile: path to the file specifying the server config (usually server.ini).";

	private static final int ARGS_INDEX_CONFIG = 0;
	private static final int ARGS_COUNT = 1;

	private Config config;

	private LobbyDemon lobbyDemon;
	private PlayerList<Player> playerList = new PlayerList<Player>(true);

	public void execute() {
		Thread playerListDemonThread = new Thread(lobbyDemon);
		playerListDemonThread.start();
		try {
			while(System.in.read() != '\n') {
			}
		}
		catch(IOException e) {
			e.printStackTrace(); //TODO : auto generated stub
		}
	}

	public void startup() throws StartupException {
		logger.info("Starting up server ...");
		try {
			ActiveClientList clients = new ActiveClientList();
			ServerSender sender = new ServerSender(Config.getInstance().getResponseUdpPort(), clients);
			lobbyDemon = new LobbyDemon(clients, sender, playerList);
		}
		catch(SocketException e) {
			throw new StartupException(e);
		}
		logger.info("Startup complete");
	}

	private void shutdown() {
		logger.info("Shutting down server ...");
		if(lobbyDemon != null) {
			lobbyDemon.shutdown();
		}
		logger.info("Shutdown complete");
	}

	public static void main(String[] args) {
//		float b[] = {423.2664f, 0.23562f, 0, 1, -1, 10.346346f, -20.236236f, 42, 553.235236f, -2456.236236f -278.0000f, Float.MAX_VALUE, Float.MIN_VALUE};
//
//		for(float c : b) {
//			System.out.println(c + " = " + Util.makeFloat(Util.makeBytes(c), 0));
//		}
//		System.out.println((1.0f > 1.0f + Float.MIN_VALUE));
//		if(true) return;

		if(args.length != ARGS_COUNT) {
			System.err.println(USAGE);
			return;
		}
		try {
			new ConfigReader().initializeConfig(args[ARGS_INDEX_CONFIG]);
			Config.getInstance().validate();
		}
		catch(ConfigReaderException e) {
			logger.fatal(e);
			return;
		}
		catch(ConfigValidationException e) {
			logger.fatal(e);
			return;
		}


		MoltenCore core = new MoltenCore();

		try {
			core.startup();
			core.execute();
		}
		catch(StartupException e) {
			logger.fatal(e);
		}
		finally {
			core.shutdown();
		}
	}
}
